﻿using Caliburn.Micro;
using SD.Common;
using SD.Infrastructure.DTOBase;
using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SD.IOC.Core.Mediators;
using SlamDunk.MES.Client.ViewModels.ExecutionPlan;
using SlamDunk.MES.Client.ViewModels.Facility;
using SlamDunk.MES.Client.ViewModels.MaterialBarcode;
using SlamDunk.MES.Client.ViewModels.ProductionPlan;
using SlamDunk.MES.Client.ViewModels.StockQuery;
using SlamDunk.MES.IAppService.DTOs.Inputs;
using SlamDunk.MES.IAppService.DTOs.Outputs.PlanContext;
using SlamDunk.MES.IAppService.DTOs.Outputs.ResourceContext;
using SlamDunk.MES.IAppService.DTOs.Outputs.StockContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.MES.Presentation.Enums;
using SlamDunk.MES.Presentation.Maps;
using SlamDunk.MES.Presentation.Models.NotifyModels;
using SlamDunk.MES.ReportView.Models;
using SlamDunk.ValueObjects.Enums;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace SlamDunk.MES.Client.ViewModels.StockOutOrder
{
    /// <summary>
    /// 出库单据添加ViewModel
    /// </summary>
    public class AddViewModel : ScreenBase
    {
        #region # 字段及构造器
        /// <summary>
        /// 库存单据服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IStockOrderContract> _iStockOrderContract;

        /// <summary>
        /// 资源定义服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IResourceContract> _iResourceContract;

        /// <summary>
        /// 基础定义服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IFoundationContract> _iFoundationContract;

        /// <summary>
        /// 编号生成服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<INumberContract> _iNumberContract;

        /// <summary>
        /// 资源定义服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IPlanContract> _iPlanContract;

        /// <summary>
        /// 基础定义服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IStockManageContract> _iStockManageContract;

        /// <summary>
        /// 窗口管理器
        /// </summary>
        private readonly IWindowManager _windowManager;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public AddViewModel(ServiceProxy<IStockOrderContract> iStockOrderContract, ServiceProxy<IResourceContract> iResourceContract, ServiceProxy<IFoundationContract> iFoundationContract, ServiceProxy<INumberContract> iNumberContract, ServiceProxy<IPlanContract> iPlanContract, ServiceProxy<IStockManageContract> iStockManageContract, IWindowManager windowManager)
        {
            this._iStockOrderContract = iStockOrderContract;
            this._iResourceContract = iResourceContract;
            this._iFoundationContract = iFoundationContract;
            this._windowManager = windowManager;
            this._iNumberContract = iNumberContract;
            this._iPlanContract = iPlanContract;
            this._iStockManageContract = iStockManageContract;
        }

        #endregion

        #region 属性
        #region 单据编号
        /// <summary>
        /// 单据编号
        /// </summary>
        [DependencyProperty]
        public string Number { get; set; }
        #endregion

        #region 单据类型列表
        /// <summary>
        /// 单据类型列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<StockOrderClassInfo> StockOrderClassList { get; set; }
        #endregion

        #region 源单据类型列表
        /// <summary>
        /// 源单据类型列表
        /// </summary>
        [DependencyProperty]
        public IDictionary<string, string> SourceOrderTypes { get; set; }
        #endregion

        #region 源单据编号
        /// <summary>
        /// 源单据编号
        /// </summary>
        [DependencyProperty]
        public string SourceOrder { get; set; }
        #endregion

        #region 源单据Id
        /// <summary>
        /// 源单据Id
        /// </summary>
        [DependencyProperty]
        public string SourceOrderId { get; set; }
        #endregion

        #region 源储存类型列表
        /// <summary>
        /// 源储存类型列表
        /// </summary>
        [DependencyProperty]
        public IDictionary<string, string> SourceStorageLocationTypes { get; set; }
        #endregion

        #region 源储存位置列表
        /// <summary>
        /// 源储存位置列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<IdentiferNameNm> SourceStorageLocations { get; set; }
        #endregion

        #region 源储存位置描述
        /// <summary>
        /// 源储存位置描述
        /// </summary>
        [DependencyProperty]
        public string SourceStorageLocationnText { get; set; }
        #endregion

        #region 源库位列表显示隐藏
        /// <summary>
        /// 源库位列表显示隐藏
        /// </summary>
        [DependencyProperty]
        public Visibility SourceStorageLocationComboBoxVisibility { get; set; }
        #endregion

        #region 源库位描述显示隐藏
        /// <summary>
        /// 源库位描述显示隐藏
        /// </summary>
        [DependencyProperty]
        public Visibility SourceStorageLocationTextVisibility { get; set; }
        #endregion

        #region 目标库类型列表
        /// <summary>
        /// 目标库类型列表
        /// </summary>
        [DependencyProperty]
        public IDictionary<string, string> TargetStorageLocationTypes { get; set; }
        #endregion

        #region 目标库位置列表
        /// <summary>
        /// 目标库位置列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<IdentiferNameNm> TargetStorageLocations { get; set; }
        #endregion

        #region 目标储存位置描述
        /// <summary>
        /// 目标储存位置描述
        /// </summary>
        [DependencyProperty]
        public string TargetStorageLocationText { get; set; }
        #endregion

        #region 目标库位列表显示隐藏
        /// <summary>
        /// 目标库位列表显示隐藏
        /// </summary>
        [DependencyProperty]
        public Visibility TargetStorageLocationComboBoxVisibility { get; set; }
        #endregion

        #region 目标库位描述显示隐藏
        /// <summary>
        /// 目标库位描述显示隐藏
        /// </summary>
        [DependencyProperty]
        public Visibility TargetStorageLocationTextVisibility { get; set; }
        #endregion

        #region 描述
        /// <summary>
        /// 描述
        /// </summary>
        [DependencyProperty]
        public string Description { get; set; }
        #endregion

        #region 已选单据类型列表
        /// <summary>
        /// 已选单据类型列表
        /// </summary>
        [DependencyProperty]
        public StockOrderClassInfo SelectedStockOrderClass { get; set; }
        #endregion

        #region 已选源单据类型
        /// <summary>
        /// 已选源单据类型
        /// </summary>
        [DependencyProperty]
        public SourceOrderTypeEnum? SelectedSourceOrderType { get; set; }
        #endregion

        #region 已选源储存类型列表
        /// <summary>
        /// 已选源储存类型列表
        /// </summary>
        [DependencyProperty]
        public StorageLocationType? SelectedSourceStorageLocationType { get; set; }
        #endregion

        #region 已选源储存位置列表
        /// <summary>
        /// 已选源储存位置列表
        /// </summary>
        [DependencyProperty]
        public IdentiferNameNm SelectedSourceStorageLocation { get; set; }
        #endregion

        #region 已选目标库类型列表
        /// <summary>
        /// 已选目标库类型列表
        /// </summary>
        [DependencyProperty]
        public StorageLocationType? SelectedTargetStorageLocationType { get; set; }
        #endregion

        #region 已选目标库位置列表
        /// <summary>
        /// 已选目标库位置列表
        /// </summary>
        [DependencyProperty]
        public IdentiferNameNm SelectedTargetStorageLocation { get; set; }
        #endregion

        #region 出库单据明细列表
        /// <summary>
        /// 出库单据明细集合
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<StockInOrderDetailNm> DetailParams { get; set; }
        #endregion

        #region 物料需求列表
        /// <summary>
        /// 物料需求列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<ExecutionMaterialAskInfo> ExecutionMaterialAsks { get; set; }
        #endregion

        #region 工厂模型名称
        /// <summary>
        /// 工厂模型名称
        /// </summary>
        [DependencyProperty]
        public string FacilityName { get; set; }
        #endregion

        #region 工厂模型Id
        /// <summary>
        /// 工厂模型Id
        /// </summary>
        [DependencyProperty]
        public Guid? FacilityId { get; set; }
        #endregion
        #endregion

        #region 方法

        //Initializations

        #region 初始化 —— override async Task OnInitializeAsync(CancellationToken cancellationToken)
        /// <summary>
        /// 初始化
        /// </summary>
        protected override async Task OnInitializeAsync(CancellationToken cancellationToken)
        {
            //初始化源储存类型
            this.SourceStorageLocationTypes = typeof(StorageLocationType).GetEnumMembers();
            this.TargetStorageLocationTypes = typeof(StorageLocationType).GetEnumMembers();
            //初始化源单据类型
            this.SourceOrderTypes = typeof(SourceOrderTypeEnum).GetEnumMembers();
            //初始化单据类型列表
            PageModel<StockOrderClassInfo> StockOrderClassInfos = await Task.Run(() => this._iStockOrderContract.Channel.GetStockOrderClassesByPage(null, StockDirectionType.Output, null, null, 1, int.MaxValue));
            this.StockOrderClassList = new ObservableCollection<StockOrderClassInfo>(StockOrderClassInfos.Datas);
            //显示隐藏源库位列表
            this.SourceStorageLocationComboBoxVisibility = Visibility.Visible;
            this.SourceStorageLocationTextVisibility = Visibility.Collapsed;
            //显示隐藏目标库位列表
            this.TargetStorageLocationComboBoxVisibility = Visibility.Visible;
            this.TargetStorageLocationTextVisibility = Visibility.Collapsed;
            DetailParams = new ObservableCollection<StockInOrderDetailNm>();
        }
        #endregion


        //Actions

        #region 加载入库单编号
        /// <summary>
        /// 加载入库单编号
        /// </summary>
        public async void LoadStockOrderClass()
        {
            this.Busy();

            this.Number = await Task.Run(() => this._iNumberContract.Channel.GenerateStockOrderNo(
                         SelectedStockOrderClass.Number)//上级节点Id
                    );

            this.Idle();
        }
        #endregion

        #region 清空源单据重选 —— async void ClearSourceOrder()
        /// <summary>
        /// 清空源单据重选
        /// </summary>
        public async void ClearSourceOrder()
        {
            //清空物料需求
            this.ExecutionMaterialAsks = new ObservableCollection<ExecutionMaterialAskInfo>();
            this.SourceOrderId = null;
            this.SourceOrder = null;
        }
        #endregion


        #region 源单据重选 —— async void SelectSourceOrder()
        /// <summary>
        /// 源单据重选
        /// </summary>
        public async void SelectSourceOrder()
        {
            await JumpChoiceStockOutView();
        }
        #endregion

        #region 加载源储存位置
        /// <summary>
        /// 加载源储存位置
        /// </summary>
        public async void LoadSourceStorageLocationType()
        {
            this.Busy();

            //清空单据明细
            this.DetailParams = new ObservableCollection<StockInOrderDetailNm>();

            await this.ReloadSourceStorageLocation();

            this.Idle();
        }
        #endregion

        #region 加载目标库位置
        /// <summary>
        /// 加载目标库位置
        /// </summary>
        public async void LoadTargetStorageLocationType()
        {
            this.Busy();

            await this.ReloadTargetStorageLocation();

            this.Idle();
        }
        #endregion

        #region 库存出库
        /// <summary>
        /// 库存出库
        /// </summary>
        public async void CreateStockManage()
        {

            SelectMaterialStockViewModel viewModel = ResolveMediator.Resolve<SelectMaterialStockViewModel>();
            string storageLocationTxt = SelectedSourceStorageLocationType == StorageLocationType.Description ? SourceStorageLocationnText : SelectedSourceStorageLocation?.Id.ToString();
            viewModel.Load(FacilityId, null, SelectedSourceStorageLocationType, storageLocationTxt, true);
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                List<MaterialStockInfo> MaterialStockList = viewModel.MaterialStocks.Where(x => x.IsChecked == true).Select(x => x.Model).ToList();
                foreach (var item in MaterialStockList)
                {
                    CreateDetailParam(
                         item.MaterialId, //物料定义Id
                         item.MaterialName, //物料名称
                         item.MaterialNo,//物料编号
                         item.MaterialLotId, //物料批次Id
                         item.ProductionBatchNo, //物料批次
                         item.SupplierId,//供应商Id
                         item.SupplierName,//供应商名称
                         item.ProducedDate, //生产日期
                         item.GuaranteePeriod,//保质期
                         item.ExpiredDate, //过期日期
                         item.Specification,//规格
                         item.StockQuantity, //数量
                         0,//排序
                         null, //描述
                         null,
                         null,
                         item.QuantityUnitNo,
                         null,
                         BarcodeMode.General
                     );
                }
            }
        }
        #endregion

        #region 扫码出库
        /// <summary>
        /// 扫码出库
        /// </summary>
        public async void CreateScanCode()
        {
            ScanViewModel viewModel = ResolveMediator.Resolve<ScanViewModel>();
            viewModel.Load();
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                this.Busy();
                IDictionary<string, MaterialBarcodeInfo> materialBarcodes = await Task.Run(() => this._iStockManageContract.Channel.GetMaterialBarcodesByNo(viewModel.BarcodeNos));
                //查询通用码数据数量
                var materialBarcodeList = materialBarcodes.Where(x => x.Value == null).Select(x => x.Key).ToList();
                if (materialBarcodeList.Any())
                {
                    //根据编号获取物料定义字典
                    var barcodes = await Task.Run(() => this._iResourceContract.Channel.GetMaterialsByNo(materialBarcodeList));
                    foreach (var barcode in barcodes)
                    {
                        CreateDetailParam(
                          barcode.Value.Id, //物料定义Id
                          barcode.Value.Name, //物料名称
                          barcode.Value.Number,//物料编号
                          null, //物料批次Id
                          null, //物料批次
                          null,//供应商Id
                          null,//供应商名称
                          null, //生产日期
                         TimeSpan.FromDays(0),//保质期
                          null, //过期日期
                          barcode.Value.Specification,//规格
                          1, //数量
                          0,//排序
                          null, //描述
                          null,
                          null,
                          barcode.Value.StandardUnitNo,
                          Number,
                          BarcodeMode.General
                      );
                    }
                }
                //循环唯一码数据
                foreach (var materialBarcode in materialBarcodes.Where(x => x.Value != null))
                {
                    CreateDetailParam(
                       materialBarcode.Value.MaterialId, //物料定义Id
                       materialBarcode.Value.MaterialInfo.Name, //物料名称
                       materialBarcode.Value.MaterialInfo.Number,//物料编号
                       materialBarcode.Value.MaterialLotId.Value, //物料批次Id
                       materialBarcode.Value.MaterialLotInfo.ProductionBatchNo, //物料批次
                       materialBarcode.Value.MaterialLotInfo.SupplierId,//供应商Id
                       materialBarcode.Value.MaterialLotInfo.SupplierName,//供应商名称
                       materialBarcode.Value.MaterialLotInfo.ProducedDate, //生产日期
                       materialBarcode.Value.MaterialLotInfo.GuaranteePeriod,//保质期
                       materialBarcode.Value.MaterialLotInfo.ExpiredDate, //过期日期
                       materialBarcode.Value.MaterialLotInfo.Specification,//规格
                       materialBarcode.Value.Quantity, //数量
                       0,//排序
                       null, //描述
                       materialBarcode.Value.MaterialLotInfo.MaterialSourceType,
                       DateTime.Now,
                       materialBarcode.Value.MaterialInfo.StandardUnitNo,
                       Number,
                       BarcodeMode.Unique);
                }
                this.Idle();
            }
        }
        #endregion

        #region 清空工厂模型 —— async void ClearFacility()
        /// <summary>
        /// 清空工厂模型
        /// </summary>
        public async void ClearFacility()
        {
            this.FacilityId = null;
            this.FacilityName = "";
        }
        #endregion

        #region 加载工厂模型-弹出层
        /// <summary>
        /// 加载工厂模型-弹出层
        /// </summary>
        public async void SelectFacility()
        {
            this.Busy();
            SelectFacilityViewModel viewModel = ResolveMediator.Resolve<SelectFacilityViewModel>();
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                FacilityId = viewModel.SelectedFacility.Id;
                FacilityName = viewModel.SelectedFacility.Name;
            }
            this.Idle();
        }
        #endregion

        #region 删除单据明细
        /// <summary>
        /// 删除单据明细
        /// </summary>
        public async void RemoveStockOut(StockInOrderDetailNm stockInOrderDetailNm)
        {
            this.Busy();
            //清除单据明细缓存
            DetailParams.Remove(stockInOrderDetailNm);
            this.Idle();
        }
        #endregion

        #region 提交 —— async void Submit()
        /// <summary>
        /// 提交
        /// </summary>
        public async void Submit()
        {
            #region # 验证
            if (SelectedStockOrderClass == null)
            {
                MessageBox.Show("请选择单据类型！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            if (SelectedSourceStorageLocationType == null)
            {
                MessageBox.Show("请选择源存储类型！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            if (SelectedSourceStorageLocationType == StorageLocationType.Description)
            {
                if (string.IsNullOrEmpty(SourceStorageLocationnText))
                {
                    MessageBox.Show("请输源存储存位置！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }
            else
            {
                if (SelectedSourceStorageLocation == null)
                {
                    MessageBox.Show("请选择源存储位置！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }
            if (SelectedTargetStorageLocationType == null)
            {
                MessageBox.Show("请选择目标库类型！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            if (SelectedTargetStorageLocationType == StorageLocationType.Description)
            {
                if (string.IsNullOrEmpty(TargetStorageLocationText))
                {
                    MessageBox.Show("请输入目标库位置！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }
            else
            {
                if (SelectedTargetStorageLocation == null)
                {
                    MessageBox.Show("请选择目标库位置！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }
            if (DetailParams.Count == 0)
            {
                MessageBox.Show("出库明细不能为空，至少需要一条数据！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            #endregion

            List<StockOutOrderDetailParam> StockOutOrderDetailParams = new List<StockOutOrderDetailParam>();
            foreach (var detailParam in DetailParams)
            {
                StockOutOrderDetailParam stockOutOrderDetailParam = new StockOutOrderDetailParam();
                stockOutOrderDetailParam.materialId = detailParam.MaterialId.Value;
                stockOutOrderDetailParam.materialLotId = detailParam.MaterialLotId;
                stockOutOrderDetailParam.quantity = detailParam.Quantity.Value;
                stockOutOrderDetailParam.sort = detailParam.Sort;
                stockOutOrderDetailParam.relatedBarcodeNos = detailParam.RelatedBarcodeNos;
                StockOutOrderDetailParams.Add(stockOutOrderDetailParam);
            }
            this.Busy();
            SourceOrderType? sourceOrderType = null;
            if (SelectedSourceOrderType != null)
            {
                sourceOrderType = (SourceOrderType)SelectedSourceOrderType;
            }
            await Task.Run(() => this._iStockOrderContract.Channel.CreateStockOutOrder(
                  Number,//单据编号
                  SelectedStockOrderClass.Id,//库存单据类Id
                  sourceOrderType,//源单据类型
                  SourceOrderId,//源单据Id
                  SourceOrder,//源单据名称
                  SelectedSourceStorageLocationType.Value,//源储存位置类型
                  SelectedSourceStorageLocationType == StorageLocationType.Description ? SourceStorageLocationnText : SelectedSourceStorageLocation.Id.ToString(),//源储存位置Id
                  SelectedSourceStorageLocationType == StorageLocationType.Description ? SourceStorageLocationnText : SelectedSourceStorageLocation.Name,//源储存位置名称
                  SelectedTargetStorageLocationType.Value,//目标储存位置类型
                  SelectedTargetStorageLocationType == StorageLocationType.Description ? TargetStorageLocationText : SelectedTargetStorageLocation.Id.ToString(),//目标储存位置Id
                  SelectedTargetStorageLocationType == StorageLocationType.Description ? TargetStorageLocationText : SelectedTargetStorageLocation.Name,//目标储存位置名称
                  FacilityId,//工厂模型Id
                  Description,//描述
                  StockOutOrderDetailParams));
            await base.TryCloseAsync(true);
            this.Idle();
        }
        #endregion


        //Private

        #region 跳转作业计划/生产计划页面 —— async Task JumpChoiceStockOutView()
        /// <summary>
        /// 跳转出库单页面
        /// </summary>
        private async Task JumpChoiceStockOutView()
        {
            if (SelectedSourceOrderType == SourceOrderTypeEnum.ExecutionPlan)
            {
                SelectExecutionPlanViewModel viewModel = ResolveMediator.Resolve<SelectExecutionPlanViewModel>();
                viewModel.Load(false, FacilityId, null, null);
                bool? result = await this._windowManager.ShowDialogAsync(viewModel);
                if (result == true)
                {
                    var ExecutionPlanInfo = viewModel.ExecutionPlans.Where(x => x.IsChecked == true).FirstOrDefault();
                    SourceOrderId = ExecutionPlanInfo.Model.Id.ToString();
                    SourceOrder = ExecutionPlanInfo.Model.Number;
                    ExecutionMaterialAsks = new ObservableCollection<ExecutionMaterialAskInfo>(await Task.Run(() => this._iPlanContract.Channel.GetExecutionMaterialAsks(Guid.Parse(SourceOrderId))));
                }
            }
            else if (SelectedSourceOrderType == SourceOrderTypeEnum.ProductionPlan)
            {
                SelectProductionPlanViewModel viewModel = ResolveMediator.Resolve<SelectProductionPlanViewModel>();
                viewModel.Load(false, null, FacilityId);
                bool? result = await this._windowManager.ShowDialogAsync(viewModel);
                if (result == true)
                {
                    var ExecutionPlanInfo = viewModel.ProductionPlans.Where(x => x.IsChecked == true).FirstOrDefault();
                    SourceOrderId = ExecutionPlanInfo.Model.Id.ToString();
                    SourceOrder = ExecutionPlanInfo.Model.Number;
                    ExecutionMaterialAsks = new ObservableCollection<ExecutionMaterialAskInfo>();
                    var ProductionMaterialAskList = new ObservableCollection<ProductionMaterialAskInfo>(await Task.Run(() => this._iPlanContract.Channel.GetProductionMaterialAsks(Guid.Parse(SourceOrderId))));
                    foreach (var productionMaterialAskInfo in ProductionMaterialAskList)
                    {
                        ExecutionMaterialAsks.Add(new ExecutionMaterialAskInfo()
                        {
                            Id = productionMaterialAskInfo.Id,
                            Number = productionMaterialAskInfo.Number,
                            Name = productionMaterialAskInfo.Number,
                            AddedTime = productionMaterialAskInfo.AddedTime,
                            MaterialId = productionMaterialAskInfo.MaterialId,
                            MaterialLotId = productionMaterialAskInfo.MaterialLotId,
                            Quantity = productionMaterialAskInfo.Quantity,
                            Sort = productionMaterialAskInfo.Sort,
                            Description = productionMaterialAskInfo.Description,
                            MaterialInfo = productionMaterialAskInfo.MaterialInfo,
                            MaterialLotInfo = productionMaterialAskInfo.MaterialLotInfo
                        });
                    }
                }
            }
        }
        #endregion

        #region 加载源储存位置列表 —— async Task ReloadSourceStorageLocation()
        /// <summary>
        /// 加载源储存位置列表
        /// </summary>
        public async Task ReloadSourceStorageLocation()
        {
            #region # 验证

            if (this.SelectedSourceStorageLocationType == null)
            {
                this.SourceStorageLocations = new ObservableCollection<IdentiferNameNm>();
                return;
            }
            #endregion

            //显示隐藏库位列表
            this.SourceStorageLocationComboBoxVisibility = Visibility.Visible;
            this.SourceStorageLocationTextVisibility = Visibility.Collapsed;
            switch (SelectedSourceStorageLocationType)
            {
                case StorageLocationType.ProductionDomain://生产域
                    IEnumerable<IAppService.DTOs.Outputs.FoundationContext.FacilityInfo> Facilities = await Task.Run(() =>
                    this._iFoundationContract.Channel.GetFacilities(
                        null,//关键字
                        null,//工厂模型层次
                        FacilityType.ProductionDomain,//工厂模型类型
                        null)//上级节点Id
                    );
                    IEnumerable<IdentiferNameNm> Facilitiemodels = Facilities.Select(x => x.ToIdentiferName());
                    SourceStorageLocations = new ObservableCollection<IdentiferNameNm>(Facilitiemodels);
                    break;
                case StorageLocationType.BusinessDomain://业务域
                    Facilities = await Task.Run(() =>
                    this._iFoundationContract.Channel.GetFacilities(
                        null,//关键字
                        null,//工厂模型层次
                        FacilityType.BusinessDomain,//工厂模型类型
                        null)//上级节点Id
                    );
                    Facilitiemodels = Facilities.Select(x => x.ToIdentiferName());
                    SourceStorageLocations = new ObservableCollection<IdentiferNameNm>(Facilitiemodels);
                    break;
                case StorageLocationType.StorageDomain://储存域
                    Facilities = await Task.Run(() =>
                   this._iFoundationContract.Channel.GetFacilities(
                      null,//关键字
                      null,//工厂模型层次
                      FacilityType.StorageDomain,//工厂模型类型
                      null)//上级节点Id
                  );
                    Facilitiemodels = Facilities.Select(x => x.ToIdentiferName());
                    SourceStorageLocations = new ObservableCollection<IdentiferNameNm>(Facilitiemodels);
                    break;
                case StorageLocationType.Person://人员
                    PageModel<PersonInfo> Persons = await Task.Run(() =>
                      this._iResourceContract.Channel.GetPersonsByPage(
                         null,//关键字
                         FacilityId,//工厂模型Id
                         null,//人员类Id
                         1,
                         int.MaxValue)//上级节点Id
                   );
                    IEnumerable<IdentiferNameNm> Personsmodels = Persons.Datas.Select(x => x.ToIdentiferName());
                    SourceStorageLocations = new ObservableCollection<IdentiferNameNm>(Personsmodels);
                    break;
                case StorageLocationType.Team://班组
                    PageModel<TeamInfo> Teams = await Task.Run(() =>
                     this._iResourceContract.Channel.GetTeamsByPage(
                        null,//关键字
                        FacilityId,//工厂模型Id
                        1,
                        int.MaxValue)//上级节点Id
                  );
                    IEnumerable<IdentiferNameNm> TeamModels = Teams.Datas.Select(x => x.ToIdentiferName());
                    SourceStorageLocations = new ObservableCollection<IdentiferNameNm>(TeamModels);
                    break;
                case StorageLocationType.Customer://客户
                    PageModel<EnterpriseInfo> Enterprises = await Task.Run(() =>
                    this._iResourceContract.Channel.GetEnterprisesByPage(
                       null,//关键字
                       EnterpriseType.Customer,//企业类型
                       FacilityId,//工厂模型Id
                       1,
                       int.MaxValue)//上级节点Id
                 );
                    IEnumerable<IdentiferNameNm> EnterpriseModels = Enterprises.Datas.Select(x => x.ToIdentiferName());
                    SourceStorageLocations = new ObservableCollection<IdentiferNameNm>(EnterpriseModels);
                    break;
                case StorageLocationType.Supplier://供应商
                    Enterprises = await Task.Run(() =>
                   this._iResourceContract.Channel.GetEnterprisesByPage(
                      null,//关键字
                      EnterpriseType.Supplier,//企业类型
                      FacilityId,//工厂模型Id
                      1,
                      int.MaxValue)//上级节点Id
                );
                    EnterpriseModels = Enterprises.Datas.Select(x => x.ToIdentiferName());
                    SourceStorageLocations = new ObservableCollection<IdentiferNameNm>(EnterpriseModels);
                    break;
                case StorageLocationType.Description://描述
                    SourceStorageLocationComboBoxVisibility = Visibility.Collapsed;
                    SourceStorageLocationTextVisibility = Visibility.Visible;
                    break;
            }
        }
        #endregion

        #region 加载目标库位置列表 —— async Task ReloadTargetStorageLocation()
        /// <summary>
        /// 加载目标库位置列表
        /// </summary>
        public async Task ReloadTargetStorageLocation()
        {
            #region # 验证

            if (this.SelectedTargetStorageLocationType == null)
            {
                this.TargetStorageLocations = new ObservableCollection<IdentiferNameNm>();
                return;
            }
            #endregion

            //显示隐藏库位列表
            this.TargetStorageLocationComboBoxVisibility = Visibility.Visible;
            this.TargetStorageLocationTextVisibility = Visibility.Collapsed;
            switch (SelectedTargetStorageLocationType)
            {
                case StorageLocationType.ProductionDomain://生产域
                    IEnumerable<IAppService.DTOs.Outputs.FoundationContext.FacilityInfo> Facilities = await Task.Run(() =>
                    this._iFoundationContract.Channel.GetFacilities(
                        null,//关键字
                        null,//工厂模型层次
                        FacilityType.ProductionDomain,//工厂模型类型
                        null)//上级节点Id
                    );
                    IEnumerable<IdentiferNameNm> Facilitiemodels = Facilities.Select(x => x.ToIdentiferName());
                    TargetStorageLocations = new ObservableCollection<IdentiferNameNm>(Facilitiemodels);
                    break;
                case StorageLocationType.BusinessDomain://业务域
                    Facilities = await Task.Run(() =>
                    this._iFoundationContract.Channel.GetFacilities(
                        null,//关键字
                        null,//工厂模型层次
                        FacilityType.BusinessDomain,//工厂模型类型
                        null)//上级节点Id
                    );
                    Facilitiemodels = Facilities.Select(x => x.ToIdentiferName());
                    TargetStorageLocations = new ObservableCollection<IdentiferNameNm>(Facilitiemodels);
                    break;
                case StorageLocationType.StorageDomain://储存域
                    Facilities = await Task.Run(() =>
                   this._iFoundationContract.Channel.GetFacilities(
                      null,//关键字
                      null,//工厂模型层次
                      FacilityType.StorageDomain,//工厂模型类型
                      null)//上级节点Id
                  );
                    Facilitiemodels = Facilities.Select(x => x.ToIdentiferName());
                    TargetStorageLocations = new ObservableCollection<IdentiferNameNm>(Facilitiemodels);
                    break;
                case StorageLocationType.Person://人员
                    PageModel<PersonInfo> Persons = await Task.Run(() =>
                      this._iResourceContract.Channel.GetPersonsByPage(
                         null,//关键字
                         FacilityId,//工厂模型Id
                         null,//人员类Id
                         1,
                         int.MaxValue)//上级节点Id
                   );
                    IEnumerable<IdentiferNameNm> Personsmodels = Persons.Datas.Select(x => x.ToIdentiferName());
                    TargetStorageLocations = new ObservableCollection<IdentiferNameNm>(Personsmodels);
                    break;
                case StorageLocationType.Team://班组
                    PageModel<TeamInfo> Teams = await Task.Run(() =>
                     this._iResourceContract.Channel.GetTeamsByPage(
                        null,//关键字
                        FacilityId,//工厂模型Id
                        1,
                        int.MaxValue)//上级节点Id
                  );
                    IEnumerable<IdentiferNameNm> TeamModels = Teams.Datas.Select(x => x.ToIdentiferName());
                    TargetStorageLocations = new ObservableCollection<IdentiferNameNm>(TeamModels);
                    break;
                case StorageLocationType.Customer://客户
                    PageModel<EnterpriseInfo> Enterprises = await Task.Run(() =>
                    this._iResourceContract.Channel.GetEnterprisesByPage(
                       null,//关键字
                       EnterpriseType.Customer,//企业类型
                       FacilityId,//工厂模型Id
                       1,
                       int.MaxValue)//上级节点Id
                 );
                    IEnumerable<IdentiferNameNm> EnterpriseModels = Enterprises.Datas.Select(x => x.ToIdentiferName());
                    TargetStorageLocations = new ObservableCollection<IdentiferNameNm>(EnterpriseModels);
                    break;
                case StorageLocationType.Supplier://供应商
                    Enterprises = await Task.Run(() =>
                   this._iResourceContract.Channel.GetEnterprisesByPage(
                      null,//关键字
                      EnterpriseType.Supplier,//企业类型
                      FacilityId,//工厂模型Id
                      1,
                      int.MaxValue)//上级节点Id
                );
                    EnterpriseModels = Enterprises.Datas.Select(x => x.ToIdentiferName());
                    TargetStorageLocations = new ObservableCollection<IdentiferNameNm>(EnterpriseModels);
                    break;
                case StorageLocationType.Description://描述
                    TargetStorageLocationComboBoxVisibility = Visibility.Collapsed;
                    TargetStorageLocationTextVisibility = Visibility.Visible;
                    break;
            }
        }
        #endregion

        #region 创建单据明细 —— async Task CreateDetailParam()
        /// <summary>
        /// 创建单据明细
        /// </summary>
        /// <param name="materialId">物料定义Id</param>
        /// <param name="materialName">物料名称</param>
        /// <param name="materialNo">物料编号</param>
        /// <param name="materialLotId">物料批次Id</param>
        /// <param name="ProductionBatchNo">物料批次</param>
        /// <param name="supplierId">供应商Id</param>
        /// <param name="SupplierName">供应商名称</param>
        /// <param name="ProducedDate">生产日期</param>
        /// <param name="GuaranteePeriod">保质期</param>
        /// <param name="ExpiredDate">过期日期</param>
        /// <param name="Specification">规格</param>
        /// <param name="InitialQuantity">数量</param>
        /// <param name="sort">排序</param>
        /// <param name="description">描述</param>
        /// <param name="materialSourceType">物料来源</param>
        /// <param name="receptionDate">接收时间</param>
        /// <param name="standardUnitNo">单位</param>
        /// <param name="barcodeNo">物料条码</param>
        /// <param name="BarcodeMode">条码模式</param>
        public void CreateDetailParam(Guid? materialId, string materialName, string materialNo, Guid? materialLotId, string ProductionBatchNo, Guid? supplierId, string SupplierName, DateTime? ProducedDate, TimeSpan? GuaranteePeriod, DateTime? ExpiredDate, string Specification, decimal InitialQuantity, int sort, string description, MaterialSourceType? materialSourceType, DateTime? receptionDate, string standardUnitNo, string barcodeNo, BarcodeMode barcodeMode)
        {
            StockInOrderDetailNm detailParamNm = null;
            if (DetailParams.Count() != 0)
            {
                var DetailParam = DetailParams.Where(x => x.MaterialId == materialId && x.MaterialLotId == materialLotId);
                if (DetailParam.Count() != 0)
                {
                    detailParamNm = DetailParam.FirstOrDefault();
                }
            }
            if (detailParamNm == null)
            {
                //添加出库单明细参数模型
                DetailParams.Add(new StockInOrderDetailNm(
                    materialId,
                    materialName,
                    materialNo,
                    materialLotId,
                    InitialQuantity,
                    sort,
                    description,
                    new List<string> { barcodeNo },
                    supplierId,
                    SupplierName,
                    ProductionBatchNo,
                    ProducedDate,
                    GuaranteePeriod,
                    ExpiredDate,
                    receptionDate,
                    Specification,
                    materialSourceType,
                    null,
                    null,
                    false,
                    false,
                    null,
                    null,
                    standardUnitNo
                    ));
            }
            else
            {
                detailParamNm.Quantity += InitialQuantity;
            }
        }
        #endregion

        #endregion
    }
}
